perm filename VISIO.PAL[AL,HE]2 blob
sn#585526 filedate 1981-05-11 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 Routines to communicate with the Vision Module via the DR11-C
C00008 00003 Interrupt routines
C00010 00004 Sending routines
C00014 00005 Receiving routines
C00017 00006 Reset & bad requests
C00018 00007 Data & Constants
C00021 ENDMK
C⊗;
;Routines to communicate with the Vision Module via the DR11-C
; COMMANDS are:
VMTRANS= 040000 ; TRANSFER DATA COMMAND
ERESET= 140000 ; RESET
ERESAK= 160000 ; RESET ACKNOWLEDGE
; STATUS word values are:
; OK= 0 ; DONE WITH A CLR
ERBUF0= 101000 ; NO BUFFERS AVAILABLE FOR INPUT MESSAGE
ERBUFS= 102000 ; NEXT BUFFER IS TOO SMALL
ERCHKS= 103000 ; CHECKSUM ERROR
;DR11-C definitions
DRCSR = 763750 ;Control and Status register
DROBUF = 763752 ;Output Buffer register
DRIBUF = 763754 ;Input Buffer register
DRIVEC = 360 ;Request A & B interrupt vectors
; .=DRIVEC
; DRINTA ;Req A interrupt handler
; 200 ;Level 4
; DRINTB ;Req B interrupt handler
; 200 ;Level 4
;Routine to send a message over to the Vision Module & await a reply.
;No arguments since we use fixed buffers & the message is already set up.
;Clobbers R0 & R1
CODE
VMSEND: TST VMINIT ;Have we initialized the DR11-C link?
BNE 3$ ; yes - skip ahead
INC VMINIT ; no - only initialize once
MOV #50040,VMPDB+UPSW ;So we use supervisor mode
FORK #VMPDB,#VMNULL,#USRDM ;Start up VM null job - so we'll have a good sp
SLEEP #200. ;Now wait for it to be set up (probably don't need this)
MOV #2,DRCSR ;Send VM a Req B, should clean things up some
SETVEC #DRIVEC,#DRINTA,#50240 ;Set up interrupt vectors
SETVEC #DRIVEC+4,#DRINTB,#50240 ;Use Supervisor mode, priority level 5
;Check that Vision Module is powered up
TST DRCSR ;See if Req B currently set
BNE 2$ ; Yes - VM must be on
1$: SETPRI #5 ;Set our priority up to 5 so we aren't interrupted
MOV #40,DRCSR ;Turn on Int B
MOV DRCSR,R0 ;Remember CSR
CLR DRCSR ;Turn off interrupts
SETPRI ;Restore our old priority
TST R0 ;Did Req B go on when we enabled interrupts?
BPL 2$ ; No - everything's okay
ALERR VMNPWR ; Yes - Complain
BR 1$ ;Let user try to fix things
;See if anyone's home
2$: MOV #6,VMSTATE ;Send a RESET & see if it gets acknowledged
MOV #ERESET,DROBUF
MOV #141,DRCSR ;Enable interrupts & Int A in VM
SLEEP #500. ;Now wait 500 msecs for the reset acknowledge
TST VMSTATE
BEQ 3$ ;VMSTATE will be set to 0 if we get the resak
ALERR VMTMES ;Time out - complain
BR 2$ ;Try again
3$: BIS #2,DRCSR ;Set CSR 1 for "B" response (may not be needed)
MOV VMSBUF,R1 ;R1 ← Message length in bytes
MOV R1,R0
INC R0 ;In case odd number of bytes
ASR R0 ;Convert bytes → word count
MOV R0,VMSCNT ;Set up word count
MOV #VMSBUF+2,VMSPTR ;Set up pointer at message
MOV #VMRBUF,VMRPTR ;Reset receive message pointer
BIS #VMTRANS,R1 ;R1 ← Send command bits + byte count
MOV R1,DROBUF ;Get ready to send it
BIC #3,DRCSR ;Clear CSR 0 & 1 bits
MOV #1,VMSTATE
CLR VMSDONE
CLR VMRDONE
INC DRCSR ;"A" Request for command
MOV #20.,R0
4$: TST VMSDONE ;Wait for it to have been sent
BNE 5$
SLEEP #50. ;Sleep for 50 msecs
SOB R0,4$ ;Try it again
ALERR VMTMES ;Time out after 1 second - complain
BR VMSEND ;Try again from the top
5$: MOV #200.,R0
6$: TST VMRDONE ;Wait for reply to have been received
BNE 7$
SLEEP #50. ;Sleep for 50 msecs
SOB R0,4$ ;Try it again
ALERR VMTMES ;Time out after 10 seconds - complain
JMP VMSEND ;Try again from the top
7$: RTS PC
;Interrupt routines
DRINTA: MOV R0,-(SP)
MOV #ADISP,R0 ;Use A dispatch table
BR DRINT
DRINTB: MOV R0,-(SP)
MOV #BDISP,R0 ;Use B dispatch table
DRINT: MOV R1,-(SP)
BIC #3,DRCSR ;Clear interrupt requests
MOV DRIBUF,R1 ;R1 ← Anything sent over to us
ADD VMSTATE,R0
ADD VMSTATE,R0 ;Get offset into dispatch table
JMP @0(R0) ;Go do it
VMINTB: BIS #2,DRCSR ;Signal with a B request
VMINTR: MOV (SP)+,R1
MOV (SP)+,R0
KRTI ;Have kernel do the RTI for us
VMNULL: MOV USKMAX+VMPDB,SP ;Make sure we have a good stack pointer
DISMIS ;Now go away
;Sending routines
; In case he's not ready to start receiving when we want to send
VMA1: BIC #777,R1 ;Clear all non-status bits
CLR VMSTATE ;So we can receive
INC VMERRS ;Update error count
CMP #ERBUF0,R1 ;No buffers error?
BNE 1$
ALERR NBFMES ;Complain
BR 4$ ; & try again
1$: CMP #ERBUFS,R1 ;Buffer too small?
BNE 2$
ALERR SBFMES ;Complain
BR 4$ ; & try again
2$: CMP #ERESET,R1 ;External Reset?
BEQ 3$
ALERR ERRMES ;Who know's what's going on?
BR 4$ ; Try again
3$: MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A
4$: INC VMRESN ;Update count of resent messages
BIC #3,DRCSR ;Clear interrupts
BIS #2,DRCSR ;Set CSR 1 for "B" response (may not be needed)
MOV VMSBUF,R1 ;R1 ← Message length in bytes
MOV R1,R0
INC R0 ;In case odd number of bytes
ASR R0 ;Convert bytes → word count
MOV R0,VMSCNT ;Set up word count
MOV #VMSBUF+2,VMSPTR ;Set up pointer at message
BIS #VMTRANS,R1 ;R1 ← Send command bits + byte count
MOV R1,DROBUF ;Get ready to send it
MOV #1,VMSTATE
INC DRCSR ;"A" Request for command
BR VMINTR ;Maybe it'll work
;It's okay with him to send - ship it over
VMB1: INC VMSTATE
CLR VMCKSUM ;Get ready to send message over
VMB2: DEC VMSCNT ;More to send?
BPL 1$ ; yes - do it
MOV VMCKSUM,DROBUF ; no - go send cksum
INC VMSTATE ; Update VMSTATE
BR VMINTB ; B Req & return
1$: MOV @VMSPTR,R0 ;Fetch next word to send
XOR R0,VMCKSUM ;Update check sum
MOV R0,DROBUF ;Move it to output buffer
ADD #2,VMSPTR ;Bump pointer
BR VMINTB ;B Req & return
;Done sending - see if he received it okay
VMA3: TST R1 ;Check status
BMI 1$ ; Error skip ahead
CLR VMSTATE ;Done here
INC VMSDONE
BR VMINTB ;B Req & return so VM can continue
1$: INC VMERRS ;Update error count
CMP #ERESET,R1 ;Remote Reset?
BNE 2$ ; no
MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A
2$: INC VMRESN ;Update count of resent messages
BIC #3,DRCSR ;Clear interrupts
BIS #2,DRCSR ;Set CSR 1 for "B" response (may not be needed)
MOV VMSBUF,R1 ;R1 ← Message length in bytes
MOV R1,R0
INC R0 ;In case odd number of bytes
ASR R0 ;Convert bytes → word count
MOV R0,VMSCNT ;Set up word count
MOV #VMSBUF+2,VMSPTR ;Set up pointer at message
BIS #VMTRANS,R1 ;R1 ← Send command bits + byte count
MOV R1,DROBUF ;Get ready to send it
MOV #1,VMSTATE
INC DRCSR ;"A" Request for command
JMP VMINTR ;Return from interrupt
;Receiving routines
;Ready to start receiving
VMA0: TST R1 ;See if transfer request
BGT 3$ ; yes - skip ahead & do it
BIC #17777,R1 ;Clear all except command bits
BNE 1$
JMP VMINTB ;Null status - just ignore
1$: CMP #ERESET,R1 ;Make sure it was a reset
BNE 2$
MOV #ERESAK,DROBUF ;Send a reset acknowledge
INC DRCSR ;Int A & return
JMP VMINTR
2$: ALERR ERRMES ;What's going on?
INC VMERRS ;Update error count
MOV #ERESET,DROBUF ;Try to reset things
INC DRCSR
MOV #6,VMSTATE ;Wait for reset acknowledgement
JMP VMINTR
3$: BIC #VMTRANS,R1 ;Clear command bits
MOV R1,@VMRPTR ;Store byte count
ADD #2,VMRPTR
INC R1 ;In case odd number of bytes
ASR R1 ;Convert bytes to words
MOV R1,VMRCNT ;Store it
CLR VMCKSUM
MOV #4,VMSTATE ;Receive data
JMP VMINTB ;B response & return
;Store the message away now
VMB4: DEC VMRCNT ;More to message?
BMI 1$ ; no - go get checksum
MOV R1,@VMRPTR ;Store data away
ADD #2,VMRPTR
XOR R1,VMCKSUM ;Accumulate checksum
JMP VMINTB ;B response & return
1$: CMP R1,VMCKSUM ;Checksum okay
BNE 2$ ; No
INC VMSTATE ; Yes - send ok status & wait til ok to proceed
CLR DROBUF
INC DRCSR ;A response & return
JMP VMINTR
2$: INC VMERRS ;Update error count
INC VMRERV ;Update count of requested retransmissions
CLR VMSTATE
MOV #ERCHKS,DROBUF
INC DRCSR ;Req A
JMP VMINTR
;Done receiving
VMB5: INC VMRDONE ;Let everyone know that we're done
CLR VMSTATE
JMP VMINTR
;Reset & bad requests
;Waiting for Reset Acknowledgement
VMA6: BIC #17777,R1 ;Strip to command bits
CMP #ERESET,R1 ;Check for VM reseting also
BNE 2$ ; no
MOV #ERESAK,DROBUF ; yes - acknowledge his
INC DRCSR ;Req A & return
1$: JMP VMINTR
2$: CMP #ERESAK,R1 ;Is VM acknowledging us?
BNE 1$ ; no - ignore it
CLR VMSTATE ; yes - ok
JMP VMINTB ;B response & return
;Ignore Req B's
VMB0: JMP VMINTR
;Bad Requests
VMABAD: ;ALERR ABDMES ;Don't Complain
INC VMERRS ;Update error count
JMP VMINTR
VMBBAD: ;ALERR BBDMES ;Don't Complain
INC VMERRS ;Update error count
JMP VMINTR
;Data & Constants
DATA
VMPDB:: PDBLK 2,40 ;So we'll have a good stack pointer for interrupts
VMINIT:: 0 ;Have we inited yet
VMSTATE:: 0 ;What we're doing:
; 0 = nothing
; 1 = waiting for ok to start sending
; 2 = sending data & cksum
; 3 = waiting for message received ok
; 4 = receiving data & cksum
; 5 = waiting for ok to continue
; 6 = reset in progress
ADISP:: .WORD VMA0,VMA1,VMABAD,VMA3,VMABAD,VMABAD,VMA6 ;Req A dispatch table
BDISP:: .WORD VMB0,VMB1,VMB2,VMBBAD,VMB4,VMB5,VMBBAD ;Req B dispatch table
VMSBUF:: .BLKW 100 ;Message to send
VMRBUF:: .BLKW 100 ;Where we store the reply to our message
VMSPTR:: VMSBUF ;What to send next
VMSCNT:: 0 ;How much left to send
VMRPTR:: VMRBUF ;Where to store next word
VMRCNT:: 0 ;How much left to receive
VMCKSUM:: 0
VMSDONE:: .WORD 0 ;Set when message has been sent
VMRDONE:: .WORD 0 ;Set when reply has been received
;Random statistics we'll never look at
VMERRS:: 0 ;# of errors
VMRESN:: 0 ;# of resent messages
VMRERV:: 0 ;# of resent replies
;Error messages
VMTMES:: .ASCIZ /πTime out - Make sure Vision Module is ready./
VMNPWR:: .ASCIZ /πVision Module not turned on. Power it up & continue./
RESMES:: .ASCIZ /πExternal reset./
NBFMES:: .ASCIZ /πNo available buffers in VM./
SBFMES:: .ASCIZ /πToo small buffer in VM./
ERRMES:: .ASCIZ /πUnknown error./
ABDMES:: .ASCIZ /πUnexpected A Request./
BBDMES:: .ASCIZ /πUnexpected A Request./
.EVEN
CODE